#include "common.hpp"

#include <set> 
static const char *optString = "p:h?";

static const struct option longOpts[] = {
	{ "help", no_argument, NULL, 'h' },
	{ "people", required_argument, NULL, 'p' },
	{ 0,0,0,0 }
};

// Clase de utilidad para la generación de nombres diferentes para cada persona.
class generador_de_nombres {
	protected:
		std::set<std::string> nombres;
		std::set<std::string>::const_iterator it;
		size_t vuelta;
	public:
		generador_de_nombres() {
			nombres.insert("Ale");
			nombres.insert("Esteban");
			nombres.insert("Jorge");
			nombres.insert("Alberto");
			nombres.insert("Pablo");
			nombres.insert("Jose");
			nombres.insert("Hector");
			nombres.insert("Miguel");
			nombres.insert("Javier");
			nombres.insert("Raul");
			vuelta = -1;
			it = nombres.end();
		}
		
		const std::string& next() {
			static std::string aux;
			aux.clear();
			if (it == nombres.end()) {
				vuelta++;
				it = nombres.begin();
			}
			aux = *it++;
			if (vuelta > 0) {
				aux+= " ";
				aux+= (char)('A'+(vuelta-1));
			}
			return aux;
		}

}; // class generador_de_nombres

int main (int argc, char* const argv[]) {
	// Parametros.
	size_t personas = 10;

	// Variables.
	int longIndex = 0;
	int option = 0;
	bool ayuda = false;

	// Interpretación de parametros.
	while ( (option = getopt_long(argc,argv,optString,longOpts,&longIndex) ) != EOF ) {
		switch (option) {
			case '?':
			case 'h':
			case ':':
				ayuda = true;
				break;
			case 'p':
				personas = parse<size_t>(optarg,0);
				break;
			default:
				break;
		}
	}

	if ( (ayuda) || (personas == 0) ) {
		std::cerr << "Proceso generador de personas." << std::endl;
		std::cerr << "\tUso: " << argv[0] << " [-h] <-name string> <-people entero>" << std::endl;
		std::cerr << "\tParametros:" << std::endl;
		std::cerr << "\t\t-h,--help:\tMostrar este mensaje de ayuda." << std::endl;
		std::cerr << "\t\t-p,--people:\tCantidad de personas a generar en la puerta." << std::endl;

		return (ayuda) ? 0 : -1;
	}

	srand( time(NULL) + getpid() );
	generador_de_nombres nombres;

	logger << "Generador de arribos: Inicio. Personas a generar " << personas << "." << nl;
	while (personas > 0) {
		personas--;

		// Ejecuto la persona con el nombre generado.
		if (fork() == 0)
			execlp("./persona","persona","-n",nombres.next().c_str(),(char*)NULL);

		usleep( rand()%3000 ); // Simula el arribo de una persona al gimnasio.
	}

	logger << "Generador de arribos: Fin." << nl;
	return 0;
}

